﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Topro.DataAccess.Impl
{
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using Topro.Entity;
    using Topro.Entity.Enum;
    using Topro.Entity.Query;
    using Topro.Entity.Response;
    using Topro.Entity.Table;
    using Topro.Enum;
    using Topro.Libraries.Data;
    using Topro.Libraries.Transaction;

    public class ASRSJOBImpl : Base, IASRSJOB
    {
        /// <summary>
        /// 获取指令
        /// </summary>
        /// <returns></returns>
        public ASRSJOBResonse GetById(int id)
        {
            var sql = "select * from asrsjob where Id=@Id";

            var list = DBContext.Sql(sql)
                                .Parameter("Id", id)
                                .QuerySingle<ASRSJOBResonse>();
            return list;
        }

        /// <summary>
        /// 获取指令
        /// </summary>
        /// <param name="orderType">类型</param>
        /// <param name="containerCode">容器</param>
        /// <param name="status">状态</param>
        /// <param name="stationNo">站台</param>
        /// <returns></returns>
        public ASRSJOBResonse GetSingle(ASRSJOBQuery query)
        {
            var list = DBContext.Select<ASRSJOBResonse>("*").From("asrsjob");
            //查询条件
            Action<string, string, object> setWhere = (@where, name, value) => list.AndWhere(@where).Parameter(name, value);

            if (string.IsNullOrEmpty(query.ORIPORT))
            {
                setWhere("ORIPORT = @ORIPORT", "ORIPORT", query.ORIPORT);
            }

            return list.QuerySingle();
        }

        /// <summary>
        /// 获取指令(编号、订单类型、站台、状态)
        /// </summary>
        /// <returns></returns>
        public ASRSJOBResonse GetSingleASC(ASRSJOBQuery query)
        {
            //SELECT * from BT_WHSHY WHERE SHYCODE LIKE '1-11-01-01%' OR SHYCODE LIKE '1-11-01-02%' ORDER BY SHYID ASC
            //查询语句
            //SELECT j.* from asrsjob j INNER JOIN t_inventory i on j.BINDID=i.ResourceId WHERE {0} And STATE in(0,1) ORDER BY i.OrderType ASC LIMIT 0,1
            //SELECT * from asrsjob WHERE {0} And STATE in(0,1) ORDER BY ID ASC LIMIT 0,1
            //var sql = string.Format("SELECT * from asrsjob WHERE {0} And STATE in(0,1) ORDER BY ID ASC LIMIT 0,1", query.Where);
            //查询
            return DBContext.Sql(query.Sql)
                                .QuerySingle<ASRSJOBResonse>();
        }

        /// <summary>
        /// 获取指令列表
        /// </summary>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public List<ASRSJOBResonse> GetList(ASRSJOBQuery query)
        {
            //查询语句
            var sql = "SELECT * from asrsjob WHERE STATE in(2,3) ORDER BY Id ASC";
            //查询
            var jobs = DBContext.Sql(sql)
                                .QueryMany<ASRSJOBResonse>();
            return jobs;
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="id">编号</param>
        /// <param name="status">状态</param>
        /// <param name="type">类型 手动(10),自动(20)</param>
        /// <returns></returns>
        public JResult UpdateStatus(int id, int status,int mode)
        {
            var result = new JResult()
            {
                Success = false
            };

            try
            {
                //查询
                var job = DBContext.Sql("select * from asrsjob where Id=@Id")
                                    .Parameter("Id", id)
                                    .QuerySingle<ASRSJOB>();
                if (job == null)
                    throw new Exception("记录不存在.");
                if(job.STATE == (int)WorkStatus.Two)
                    throw new Exception("指令已完成,无需任务操作.");
                if (job.STATE == (int)WorkStatus.Zero || job.STATE == (int)WorkStatus.One)
                {
                    //更新状态
                    var executeStatus = DBContext.Sql("update asrsjob set STATE = @STATE where Id = @Id")
                                    .Parameter("STATE", status)
                                    .Parameter("Id", job.Id)
                                    .Execute();
                    if (executeStatus <= 0)
                        throw new Exception("更新状态失败.");

                    #region 模式
                    var modeString = "";

                    if (mode == (int)CompleteMode.手动)
                        modeString = "手动";
                    else
                        modeString = "自动";
                    #endregion

                    #region 状态
                    var message = "";

                    if (status == (int)WorkStatus.Zero)
                        message = $"{modeString}重置{job.TYPE},单据号:{job.BINDID},仓位:{job.ORIPORT}->{job.TARPORT}";
                    else if (status == (int)WorkStatus.One)
                        message = $"{modeString}处理中{job.TYPE},单据号:{job.BINDID},仓位:{job.ORIPORT}->{job.TARPORT}";
                    else if (status == (int)WorkStatus.Two)
                        message = $"{modeString}完成({job.TYPE}),单据号:{job.BINDID},仓位:{job.ORIPORT}->{job.TARPORT}";
                    else if (status == (int)WorkStatus.Three)
                        message = $"{modeString}删除({job.TYPE}),单据号:{job.BINDID},仓位:{job.ORIPORT}->{job.TARPORT}";
                    #endregion

                    var log = new Log()
                    {
                        Level = 10,
                        Source = 10,
                        Message = message,
                        Ip = "127.0.0.1",
                        CreatedBy = 2,
                        CreatedDate = DateTime.Now
                    };

                    var logStatus = DBContext.Insert<Log>("log", log)
                        .AutoMap(x => x.Id)
                        .ExecuteReturnLastId<int>();
                    if (logStatus <= 0)
                        throw new Exception("新增日志失败.");

                    result.Success = true;
                }
                else
                    throw new Exception("指令已完成不能重置.");
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 手动更新状态
        /// </summary>
        /// <param name="id">编号</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public JResult MTUpdateStatus(int id, int status)
        {
            var result = new JResult()
            {
                Success = false
            };

            try
            {
                //查询
                var job = DBContext.Sql("select * from asrsjob where Id=@Id")
                                    .Parameter("Id", id)
                                    .QuerySingle<ASRSJOB>();
                if (job == null)
                    throw new Exception("记录不存在.");
                //更新状态
                var executeStatus = DBContext.Sql("update asrsjob set STATE = @STATE where Id = @Id")
                                .Parameter("STATE", status)
                                .Parameter("Id", job.Id)
                                .Execute();
                if (executeStatus <= 0)
                    throw new Exception("更新状态失败.");

                result.Success = true;

                //推送状态
                //PushTaskStatus(job).Wait();
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 盘点推送任务状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private Task PushTaskStatus(ASRSJOB task)
        {
            if (task.BINDID.Contains("PDCK") && task.TYPE.Equals("Out") && (task.STATE == 1 || task.STATE == 2))
            {
                var baseurl = System.Configuration.ConfigurationManager.AppSettings["WmsUrl"];
                var url = string.Concat(baseurl, "/CheckInv/WcsCheckTaskCallBack");
                string json = JsonConvert.SerializeObject(new { BINDID = task.BINDID, CTNCODE = task.CTNCODE, STATE = task.STATE });
                return HttpClientFactory.PostAsync(url, json);
            }

            return Task.CompletedTask;
        }

        /// <summary>
        /// 删除
        /// </summary>
        public JResult Delete(string resourceId)
        {
            var result = new JResult()
            {
                Success = false
            };

            try
            {
                //根据资源编号指令
                var jobs = DBContext.Sql("select * from asrsjob where BINDID=@BINDID")
                                .Parameter("BINDID", resourceId)
                                .QueryMany<ASRSJOBResonse>();
                //未操作数据
                var noOperCount = jobs.Where(c => c.STATE == 0).Count();
                if (jobs.Count == noOperCount)
                {
                    var job = jobs.FirstOrDefault();

                    var executeStatus = DBContext.Sql("update asrsjob set STATE = @STATE where BINDID = @BINDID")
                        .Parameter("STATE", (int)WorkStatus.Three)
                        .Parameter("BINDID", resourceId)
                        .Execute();
                    if (executeStatus <= 0)
                        throw new Exception("更新状态失败.");

                    var log = new Log()
                    {
                        Level = 10,
                        Source = 10,
                        Message = $"手动删除({job.TYPE}) 单据编号:{job.BINDID},仓位:{job.ORIPORT}-{job.TARPORT}",
                        Ip = "127.0.0.1",
                        CreatedBy = 2,
                        CreatedDate = DateTime.Now
                    };

                    var logStatus = DBContext.Insert<Log>("log", log)
                        .AutoMap(x => x.Id)
                        .ExecuteReturnLastId<int>();
                    if (logStatus <= 0)
                        throw new Exception("新增日志失败.");

                    result.Success = true;
                }
                else
                    throw new Exception("当前操作指令无法删除、部份指令已执行.");
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 指令任务
        /// </summary>
        /// <param name="id"></param>
        public JResult Job(int id)
        {
            var response = new JResult()
            {
                Success = false
            };

            using (var tran = new TransactionProvider())
            {
                try
                {
                    //获取指令
                    var job = DBContext.Sql("select j.Id,i.ResourceId,i.SourceId,i.OrderType,i.id as InventoryId,i.WarehouseUnitId,j.TYPE,j.STATE AS Status from asrsjob j INNER JOIN t_inventory i on j.BINDID=i.ResourceId WHERE j.Id=@Id")
                                        .Parameter("Id", id)
                                        .QuerySingle<JobAndInventoryResponse>();
                    if (job == null)
                    {
                        return new JResult()
                        {
                            Success = true
                        };
                    }
                    if (job.Status == (int)InventoryStatus.完成)
                    {
                        if (job.OrderType == (int)InventoryOrderType.出库 && job.Type == "Out")
                        {
                            #region 更新库存状态
                            {
                                var executeStatus = DBContext.Sql("update t_inventory set Status=@Status where ResourceId=@ResourceId")
                                                .Parameter("Status", (int)InventoryStatus.完成)
                                                .Parameter("ResourceId", job.ResourceId)
                                                .Execute();
                                if (executeStatus > 0)
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"单据号{job.ResourceId}、更新库存状态成功",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                                else
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"单据号{job.ResourceId}、更新库存状态失败",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                            }
                            #endregion

                            #region 更新来源库存
                            {
                                var executeStatus = DBContext.Sql("update t_inventory set InventoryQty=0,Disable=0 where ResourceId=@ResourceId")
                                                .Parameter("ResourceId", job.SourceId)
                                                .Execute();
                                if (executeStatus > 0)
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"单据号{job.ResourceId}、更新库存状态成功",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                                else
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"单据号{job.ResourceId}、更新库存状态失败",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                            }
                            #endregion

                            #region 释放库位
                            {
                                var updateWarehouseunitStatus = DBContext.Sql("update t_warehouseunit set Locked=0 where Id = @Id")
                                    .Parameter("Id", job.WarehouseUnitId)
                                    .Execute();
                                if (updateWarehouseunitStatus > 0)
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"单据号{job.ResourceId}、释放库位({job.WarehouseUnitId})成功",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                                else
                                {
                                    #region 日志
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"释放库位({job.WarehouseUnitId})失败",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };

                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                    #endregion
                                }
                            }
                            #endregion
                        }
                        else if (job.OrderType == (int)InventoryOrderType.入库 && job.Type == "In")
                        {
                            #region 更新库存状态
                            var executeStatus = DBContext.Sql("update t_inventory set Status = @Status where ResourceId = @ResourceId")
                                                .Parameter("Status", (int)InventoryStatus.完成)
                                                .Parameter("ResourceId", job.ResourceId)
                                                .Execute();
                            if (executeStatus > 0)
                            {
                                #region 日志
                                var log = new Log()
                                {
                                    Level = 10,
                                    Source = 10,
                                    Message = $"单据号{job.ResourceId}、更新库存状态成功",
                                    Ip = "127.0.0.1",
                                    CreatedBy = 2,
                                    CreatedDate = DateTime.Now
                                };

                                DBContext.Insert<Log>("log", log)
                                    .AutoMap(x => x.Id)
                                    .ExecuteReturnLastId<int>();
                                #endregion
                            }
                            else
                            {
                                #region 日志
                                var log = new Log()
                                {
                                    Level = 10,
                                    Source = 10,
                                    Message = $"单据号{job.ResourceId}、更新库存状态失败",
                                    Ip = "127.0.0.1",
                                    CreatedBy = 2,
                                    CreatedDate = DateTime.Now
                                };

                                DBContext.Insert<Log>("log", log)
                                    .AutoMap(x => x.Id)
                                    .ExecuteReturnLastId<int>();
                                #endregion
                            }
                            #endregion
                        }

                        #region 指令转历史
                        var deleteJobStatus = DBContext.Delete("asrsjob")
                                                .Where("Id", job.Id)
                                                .Execute();
                        if (deleteJobStatus > 0)
                        {
                            var log = new Log()
                            {
                                Level = 10,
                                Source = 10,
                                Message = $"指令转历史{job.Id}成功",
                                Ip = "127.0.0.1",
                                CreatedBy = 2,
                                CreatedDate = DateTime.Now
                            };
                            DBContext.Insert<Log>("log", log)
                                .AutoMap(x => x.Id)
                                .ExecuteReturnLastId<int>();
                        }
                        #endregion

                        tran.Commit();
                        response.Success = true;
                    }
                }
                catch (Exception ex)
                {
                    var log = new Log()
                    {
                        Level = 10,
                        Source = 10,
                        Message = ex.Message,
                        Ip = "127.0.0.1",
                        CreatedBy = 2,
                        CreatedDate = DateTime.Now
                    };

                    DBContext.Insert<Log>("log", log)
                        .AutoMap(x => x.Id)
                        .ExecuteReturnLastId<int>();

                    response.Message = ex.Message;
                }
                finally
                {
                    tran.Dispose();
                }
            }

            return response;
        }

        /// <summary>
        /// 获取指令列表
        /// </summary>
        /// <returns></returns>
        public List<ASRSJOBQueryResponse> ASRSJOBPager(ASRSJOBQuery query)
        {
            var files = @"ID,
BINDID,
TYPE,
CTNCODE,
ORIPORT,
TARPORT,
STATE,
CREATEDATE,
COMDATE";
            var tableName = "asrsjob";
            var orderby = "ORDER BY CREATEDATE ASC";
            var where = "where 1=1";

            #region 条件
            if (query.States.Any())
            {
                where += string.Format(" and STATE in({0})", string.Join(",", query.States));
            }
            #endregion

            //查询Sql
            var querySql = string.Format("select {0} from {1} {2} {3}", files, tableName, where, orderby);
            //执行查询
            var list = DBContext.Sql(querySql)
                                .QueryMany<ASRSJOBQueryResponse>();

            return list;
        }
    }
}
